<?php
/**
 * Created by PhpStorm.
 * User: stc17
 * Date: 2020/3/5
 * Time: 9:54
 *
 */
namespace SwoCloud\Server;;

use Swoole\Coroutine\Http\Client;
use SwoStar\Console\Input;
use Swoole\Server as SwooleServer;
use Swoole\WebSocket\Server as SwooleWebSocketServer;
use Swoole\Http\Request as SwooleRequest;
use Swoole\Http\Response as SwooleResponse;
use Redis;
/*
 * Route作用：
 * 1. 检测IM-server的存活状态
 * 2. 支持权限认证
 * 3. 根据服务器的状态，按照一定的算法，计算出该客户端连接到哪台IM-server，
 *  返回给客户端，客户端再去连接到对应的服务端,保存客户端与IM-server的路由关系
 * 4. 如果 IM-server宕机，会自动从Redis中当中剔除
 * 5. IM-server上线后连接到Route，自动加 入Redis（im-server 的ip ，port）
 * 6. 可以接受来自PHP代码、C++程序、Java程序的消息请求，转发给用户所在的IM-server
 * 7. 缓存服务器地址，多次查询redis

 */


class Route extends Server
{

    protected $serverKey='im_server';

    protected $redis=null;

    protected $dispatcher=null;

    protected $arithmetic='round';

    public function onWorkerStart(SwooleServer $server, int $worker_id)
    {
        $this->redis=new Redis;
        $this->redis->pconnect("192.168.157.240",6379);
        $this->redis->auth('123456');
    }

    public  function onOpen(SwooleServer $server, $request)
    {
    dd('open');
    }

    //处理im-server 注册的请求
    public  function onMessage(SwooleServer $server, $frame)
    {

        $data=\json_decode($frame->data,true);
        $fd=$frame->fd;
        //注册信息
        $this->getDispatcher()->{$data['method']}($this,$server,...[$fd,$data]);
    }
    public  function onClose($ser, $fd){
        dd('close');
    }

    //客户端向route 发起http请求验证
    public  function onRequest(SwooleRequest $request,SwooleResponse $response)
    {
        $uri = $request->server['request_uri'];
        if ($uri == '/favicon.ico') {
            $response->status(404);
            $response->end('');
            return null;
        }

        //解决跨域
        $response->header('Access-Control-Allow-Origin','*');
        $response->header('Access-Control-Allow-Methods','GET,POST');
        /*
         [
           'method'=>'login'
         ]
         * */

        $this->getDispatcher()->{$request->post['method']}($this,$request,$response);
    }

    /**
     * 创建服务
     */
    public  function createServer()
    {
        $this->swooleServer=new SwooleWebSocketServer($this->host,$this->port);
       Input::info('websocket server 访问 ws://192.168.157.240:'.$this->port);
    }


    //指定给某一个服务器连接发送信息
    public function send($ip,$port,$data,$header=null)
    {
        //携带任务id
        $unipid=session_create_id();
        $data['msg_id'] = $unipid;

        $cli= new Client($ip,$port);
        empty($header)?:$cli->setHeaders($header);

       if($cli->upgrade('/')){
           $cli->push(\json_encode($data));
       }


       //发送成功之后调用，是否确认接收
        $this->confirmGo($unipid,$data,$cli);
    }
    /**
     * 初始化监听的事件
     */
    protected  function initEvent()
    {
        $this->setEvent('sub',[
            'request'   =>'onRequest',
            'open'      =>'onOpen',
            'message'   =>'onMessage',
            'close'     =>'onClose',
        ]);
    }

    public function getDispatcher()
    {
        if(empty($this->dispatcher)){
            $this->dispatcher=new Dispatcher();
        }
        return $this->dispatcher;
    }

    //获取所有服务器可连接的
    public function getIMServers(){
        return $this->getRedis()->smembers($this->getServerKey());
    }
    public function getRedis()
    {
        return $this->redis;
    }

    public function getServerKey()
    {
        return $this->serverKey;
    }

    public function getArithmetic(){
        return $this->arithmetic;
    }
}